﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.DataStruct;
using UtilZ.Dotnet.Ex.Model;

namespace ConAppCore.Test
{
    unsafe internal class TestDataMerger
    {
        public static void Test()
        {
            //TestTake1();
            //TestTake2();
            //TestTake3();

            TestValueTypeDataMergerTake1();
            //TestPer();
        }


        private static void TestPer()
        {
            Stopwatch stopwatch = new Stopwatch();
            int length = 600000;
            int testCount = 10000;

            short[] buffer = new short[length];
            //var dataMerger = new ValueTypeDataMerger<short>(new ValueTypeDataMergerOptions() { InitCapcity = length });

            //stopwatch.Restart();
            //for (int i = 0; i < testCount; i++)
            //{
            //    dataMerger.Append(buffer);
            //    dataMerger.Take(buffer, 0, buffer.Length);
            //}
            //stopwatch.Stop();
            //Console.WriteLine($"DataMerger 循环次数:{testCount},时间:{stopwatch.Elapsed.TotalMilliseconds}ms");


            using var dataMerger2 = new ValueTypeDataMerger<short>(new ValueTypeDataMergerOptions() { InitCapcity = length });
            short* ptr = (short*)NativeMemory.Alloc(new nuint((uint)(sizeof(short) * length)));
            stopwatch.Restart();
            for (int i = 0; i < testCount; i++)
            {
                dataMerger2.Append(ptr, length);
                dataMerger2.Take(ptr, length);
            }
            stopwatch.Stop();
            Console.WriteLine($"ValueTypeDataMerger 循环次数:{testCount},时间:{stopwatch.Elapsed.TotalMilliseconds}ms");
            NativeMemory.Free(ptr);


            stopwatch.Restart();
            for (int i = 0; i < testCount; i++)
            {
                fixed (short* ptr2 = buffer)
                {
                    dataMerger2.Append(ptr2, buffer.Length);
                }

                fixed (short* ptr2 = buffer)
                {
                    dataMerger2.Take(ptr2, buffer.Length);
                }
            }
            stopwatch.Stop();
            Console.WriteLine($"ValueTypeDataMergerMix 循环次数:{testCount},时间:{stopwatch.Elapsed.TotalMilliseconds}ms");
        }

        private static void TestValueTypeDataMergerTake1()
        {
            var options = new ValueTypeDataMergerOptions()
            {
                InitCapcity = 6,
                LimitCapcity = 10,
                FullMode = ContainerFullMode.DropOld
            };
            using var dataMerger = new ValueTypeDataMerger<short>(options);
            
            dataMerger.Append(new short[] { 1, 2, 3, 4, 5 });
            SpanZ<short> spanZ1 = dataMerger.TakeSpanZ(3);
            SpanZ<short> spanZ2 = dataMerger.TakeSpanZ(dataMerger.Length);

            dataMerger.Append(new short[] { 1, 2, 3, 4, 5 });
            Span<short> span1 = dataMerger.TakeSpan(3);
            Span<short> span2 = dataMerger.TakeSpan(dataMerger.Length);

            dataMerger.Append(new short[] { 1, 2, 3, 4, 5 });
            short[] ret1 = dataMerger.Take(2);
            //short[] ret2 = dataMerger.TakeTail(2);
            //dataMerger.Append(new short[] { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 });
            dataMerger.Append(new short[] { 6, 7, 8, 9, 10, 11, 12, 13, 14 });

            short[] ret3 = dataMerger.Take(2);
            short[] ret4 = dataMerger.TakeTail(2);
        }




        private static void TestTake3()
        {
            //DataMerger<short> dataMerger = new DataMerger<short>();
            //short* ret1 = (short*)NativeMemory.Alloc((uint)sizeof(short) * 5);
            //short* ret2 = (short*)NativeMemory.Alloc((uint)sizeof(short) * 5);

            //dataMerger.Append(new short[] { 1, 2, 3, 4, 5 });
            //dataMerger.Take(ret1, 2);
            //dataMerger.TakeTail(ret2, 2);

            //dataMerger.Append(new short[] { 6, 7, 8, 9, 10 });
            //short* ret3 = (short*)NativeMemory.Alloc((uint)sizeof(short) * 5);
            //short* ret4 = (short*)NativeMemory.Alloc((uint)sizeof(short) * 5);
            //dataMerger.Take(ret3, 2);
            //dataMerger.TakeTail(ret4, 2);


            //Span<short> span1 = new Span<short>(ret1, 5);
            //Span<short> span2 = new Span<short>(ret2, 5);
            //Span<short> span3 = new Span<short>(ret3, 5);
            //Span<short> span4 = new Span<short>(ret4, 5);

            //NativeMemory.Free(ret1);
            //NativeMemory.Free(ret2);
            //NativeMemory.Free(ret3);
            //NativeMemory.Free(ret4);
        }

        private static void TestTake2()
        {
            var dataMerger = new ValueTypeDataMerger<short>();

            short[] ret1 = new short[5];
            short[] ret2 = new short[5];

            dataMerger.Append(new short[] { 1, 2, 3, 4, 5 });
            dataMerger.Take(ret1, 0, 2);
            dataMerger.TakeTail(ret2, 0, 2);
            dataMerger.Append(new short[] { 6, 7, 8, 9, 10 });


            short[] ret3 = new short[5];
            short[] ret4 = new short[5];
            dataMerger.Take(ret3, 0, 2);
            dataMerger.TakeTail(ret4, 0, 2);
        }

        private static void TestTake1()
        {
            var dataMerger = new ValueTypeDataMerger<short>();

            dataMerger.Append(new short[] { 1, 2, 3, 4, 5 });
            short[] ret1 = dataMerger.Take(2);
            short[] ret2 = dataMerger.TakeTail(2);
            dataMerger.Append(new short[] { 6, 7, 8, 9, 10 });

            short[] ret3 = dataMerger.Take(2);
            short[] ret4 = dataMerger.TakeTail(2);
        }
    }
}
